namespace ScrumSprintMonitor.TestbenchApp
{
	#region #using Directives

	using Ninject.Core;
	using Ninject.Core.Behavior;
	using Ninject.Integration.Log4net;
	using Ninject.Integration.Log4net.Infrastructure;

	using ScrumSprintMonitor.Design;
	using ScrumSprintMonitor.Extensibility;
	using ScrumSprintMonitor.Implementation;
	using ScrumSprintMonitor.Infrastructure;

	using Testbench.Impl;

	using Views.TestbenchView;

	#endregion

	internal class NinjectAppRuntimeModule : Log4netModule
	{
		/// <summary>
		/// Loads the module into the kernel.
		/// </summary>
		public override void Load()
		{
			base.Load();

			Bind<IKernel>().ToConstant(Kernel);
			Bind(typeof(ILogger<>)).To(typeof(GenericLogger<>));
			Bind(typeof(IAddInHost<>)).To(typeof(AddInHost<>));

			SetupRuntimeBindings();
		}

		private void SetupRuntimeBindings()
		{
			Bind<IResourceManager>().To<ResourceManager>().Using<SingletonBehavior>();

			var list = TestAssetLibrary.CreateWorkItems();
			foreach (var adapter in TestAssetLibrary.CreateWorkItemsWithWorkNotEstimated())
			{
				list.Add(adapter);
				list.Add(TestAssetLibrary.CreateWorkItem(list.Count, WorkItemType.UserStory, adapter.AssignedTo, adapter.State, adapter.DoneWork, adapter.RemainingWork));
			}

			Bind<IProcessTemplateAdapterProvider>().To<MefProcessTemplateAdapterProvider>().Using<SingletonBehavior>();
			Bind<IConnection>().To<TestConnection>();
			Bind<IWorkItemStore>().To<TestWorkItemStore>().Using<SingletonBehavior>().WithArgument("workItems", WritableWorkItem.ConvertToBindingList(list));
			Bind<IAvatarProviderStore>().To<AvatarProviderStore>().Using<SingletonBehavior>();

			Bind<ITestbenchViewModel>().To<TestbenchViewModel>().Using<SingletonBehavior>();
		}
	}

	internal class GenericLogger<T> : Log4netLogger,
	                                  ILogger<T>
	{
		public GenericLogger()
			: base(typeof(T))
		{
		}
	}
}